<template>
    <div class="operations">
        <div class="oper-item">
            转译工具:
            <select v-model="tool_selected">
                <option value="auto">自动</option>、
                <option value="c2rust">编译转换</option>
                <option value="chatgpt4">大模型转换</option>
                <!-- <option value="c2rust">C2Rust</option>
                <option value="chatgpt4">ChatGPT4</option>
                <option value="chatglm">智谱AI</option>
                <option value="baichuan">百川AI</option> -->
            </select>
        </div>
        <!-- <button class="oper-item" @click="handleTranscodeClick">{{ transcode_btn_text }}</button> -->
        <button class="oper-item" @click="handleEvaluationClick">{{ evaluation_btn_text }}</button>
        <div class="oper-item">
            <span :style="{ color: evaluation_pass ? '#41b883' : '#ff5555' }">{{ evaluation_result }}</span>
        </div>

        <!-- <div>
            示例：
            <select v-model="sample_selected" @change="handleSampleChange">
                <option v-for="(_, name) in C_SAMPLE" :value="name">{{ name }}</option>
            </select>
        </div>
        &nbsp; -->
        <!-- <input class="prompt" v-model="transcode_prompt" type="text" placeholder="不满意?提点建议后再次转译(我会自动在末尾附上错误信息哦)......"> -->
        <!-- <div class="oper-item">
            <label for="autoRepeatInput">
                &nbsp;&nbsp;&nbsp;自动转译重试次数:
            </label>
            <input id="autoRepeatInput" class="auto-repeat-input" :onchange="handleAutoRepeatChange" type="number" v-model="auto_repeat_times">
            &nbsp;
            <button @click="handleEvaluationClick">{{ evaluation_btn_text }}</button>
            <span :style="{ color: evaluation_pass ? '#41b883' : '#ff5555' }">{{ evaluation_result }}</span>
        </div> -->
    </div>
</template>

<script lang="ts" setup name="Operations">
    import { ref, reactive } from 'vue';
    import EventBus from '@/event_bus';
    import {
        TRANSCODE_CLICKED,
        TRANSCODE_DONE,
        EVALUATION_CLICKED,
        CPP_EXEC_DONE,
        RUST_EXEC_DONE,
        UPDATE_SERVER_TOOL,
        RUST_EXEC_ERROR
    } from '@/event_bus/events';

    import { update } from '@/api';

    const tool_selected = ref("auto");
    // 由服务器返回的最佳的工具，测评通过或者测评失败时重置
    const server_tool = ref("");
    // const tool_selected = ref("baichuan");
    const transcode_btn_text = ref("转译");
    const evaluation_btn_text = ref("转译");
    const transcode_prompt = ref('');
    const auto_repeat_times = ref(1);
    const auto_repeat_remain_times = ref(1);

    const transcode_done = ref(true);
    const evaluation_done = reactive({
        cpp: true,
        rust: true
    });
    const evaluation_result = ref("");
    const evaluation_pass = ref(true);
    const evaluation_output = reactive({
        cpp: "",
        rust: ""
    })

    const evaluation_code = reactive({
        cpp: "",
        rust: ""
    })

    EventBus.on(UPDATE_SERVER_TOOL, (tool) => {
        server_tool.value = tool as string;
    })

    function handleAutoRepeatChange() {        
        if (auto_repeat_times.value > 5) {
            auto_repeat_times.value = 5;
        } else if (auto_repeat_times.value < 1) {
            auto_repeat_times.value = 1;
        }
        auto_repeat_remain_times.value = auto_repeat_times.value;
    }

    function evaluationAllDone() {
        return evaluation_done.cpp && evaluation_done.rust
    }

    function evaluationResultCheck() {
        if (!evaluationAllDone()) return;

        // evaluation_btn_text.value = "自动转译";
        evaluation_btn_text.value = "转译";

        // console.log(evaluation_output);

        // cpp换行符是\r\n，rust是\n
        // 这里统一替换为\n
        const c_o = (evaluation_output.cpp || '').replace(/\r\n/g, "\n").trim();
        const r_o = (evaluation_output.rust || '').replace(/\r\n/g, "\n").trim();

        console.log({
            c_output: c_o,
            rust_output: r_o
        });

        auto_repeat_remain_times.value -= 1;

        if (c_o === r_o) {
            evaluation_pass.value = true;
            evaluation_result.value = "运行输出完全匹配";

            // 重置所有缓存
            evaluation_done.cpp = true;
            evaluation_done.rust = true;

            // 重置所有缓存
            evaluation_output.cpp = "";
            evaluation_output.rust = "";
            server_tool.value = "";
            EventBus.emit(RUST_EXEC_ERROR, "");

            update(evaluation_code)
                .then((response) => {
                    console.log('数据库更新结果：', response);
                })
                .catch(e => {
                    console.error('数据库更新失败：', e);
                })
        } else {
            evaluation_pass.value = false;

            // 如果选择的工具是自动，则所有的重复操作全部在服务器端完成            
            // if (auto_repeat_remain_times.value > 0 && tool_selected.value !== 'auto') {

            if (auto_repeat_remain_times.value > 0) {
                evaluation_result.value = "运行输出不匹配(剩余重试次数：" + auto_repeat_remain_times.value + ")";
                // 重新执行测评
                console.warn('测评未不通过');
                EventBus.emit(EVALUATION_CLICKED, {
                    auto_repeat: auto_repeat_times.value,
                    repeat_remain: auto_repeat_remain_times.value,
                    tool: server_tool.value || tool_selected.value,
                    prompt: '给出的代码错误，请根据错误信息修正代码',
                });
                // 重置所有缓存
                // c代码只用运行一次, 所以只清空rust的输出即可
                evaluation_done.cpp = true;
                evaluation_output.rust = "";
                evaluation_done.rust = false;

            } else {
                evaluation_result.value = "运行输出不匹配";
                // 重置所有缓存
                auto_repeat_remain_times.value = 0;
                evaluation_done.cpp = true;
                evaluation_done.rust = true;
                evaluation_output.cpp = "";
                evaluation_output.rust = "";
                server_tool.value = "";
                EventBus.emit(RUST_EXEC_ERROR, "");
            }
        }
    }

    function handleEvaluationClick() {
        if (!evaluationAllDone()) return;

        // 重置次数剩余尝试
        auto_repeat_remain_times.value = auto_repeat_times.value;

        evaluation_result.value = "";
        evaluation_done.cpp = false;
        evaluation_done.rust = false;

        evaluation_btn_text.value = "正在转译...";

        EventBus.emit(EVALUATION_CLICKED, {
            auto_repeat: auto_repeat_times.value,
            repeat_remain: auto_repeat_remain_times.value,
            tool: tool_selected.value,
        });
    }

    EventBus.on(CPP_EXEC_DONE, (data: any) => {
        evaluation_done.cpp = true;
        evaluation_output.cpp = data.exec_output;
        evaluation_code.cpp = data.exec_code;
        evaluationResultCheck();
    })

    EventBus.on(RUST_EXEC_DONE, (data: any) => {
        evaluation_done.rust = true;
        evaluation_output.rust = data.exec_output;
        evaluation_code.rust = data.exec_code;
        evaluationResultCheck();
    })

    // 转译按钮点击事件
    function handleTranscodeClick() {
        if (!transcode_done.value) return; 
        transcode_done.value = false;
        evaluation_result.value = "";

        transcode_btn_text.value = "转译中...";

        console.log('Transcode clicked!');
        console.log(`Tool selected: ${tool_selected.value}`);
        console.log(`With user prompt: ${transcode_prompt.value}`);

        EventBus.emit(TRANSCODE_CLICKED, {
            tool: tool_selected.value,
            prompt: transcode_prompt.value,
            auto_repeat: auto_repeat_times.value,
        });

        transcode_prompt.value = '';
    }

    EventBus.on(TRANSCODE_DONE, () => {
        transcode_done.value = true;
        transcode_btn_text.value = "转译";
    })


</script>

<style scoped>
    .operations {
        width: 100%;
        height: 38px;
        margin: 0 auto;
        overflow: hidden;
        background-color: #191a21;
        border-top: 1px solid rgb(189, 147, 249);
        display: flex;
        color: rgba(255, 255, 255, .5);
        cursor: default;
        user-select: none;
        vertical-align: middle;
    }

    select, button, input {
        height: 100%;
        border: none;
        outline: none;
        cursor: pointer;
        text-align: center;
        background-color: #191a21;
        color: rgba(255, 255, 255, .5);
        font-size: 16px;
        position: relative;
    }

    input.prompt {
        text-align: left;
        width: 410px;
        font-size: 14px;
        cursor: text;
        background-color: #eceff7;
        color: rgba(0, 0, 0);
        padding: 1em;
    }

    select:active, button:active {
        outline: none;
    }

    select:hover, button:hover {
        outline: none;
        background-color: #3a3b47;
    }

    button::after {
        content: "";
        position: absolute;
        width: 1px;
        height: 100%;
        background-color: rgba(255, 255, 255, .1);
        left: 0;
        top: 0;
    }

    button {
        width: 100px;
        background-color: #0077d7;
        color: #fff;
    }

    option {
        height: 1.5em;
    }

    span {
        margin-left: 10px;
        display: inline-block;
        height: 38px;
        line-height: 38px;
    }
    

    /* .operations button {
        border: 0;
        background-color: rgb(62, 64, 74);
        border-radius: 8px;
        padding: 8px 12px;
        box-shadow: 0 0 6px rgb(62, 64, 74);
        color: rgba(255, 255, 255, .5);
        cursor: pointer;
        margin-right: 20px;
        font-size: 16px;
        width: 110px;
    } */

    /* .operations button:active {
        background-color: rgb(33, 34, 44);
    } */

    .operations div {
        display: inline;
    }

    input[type=number] {
        appearance: textfield;
    }
    input[type=number]::-webkit-inner-spin-button,
    input[type=number]::-webkit-outer-spin-button {
        -webkit-appearance: none;
        margin: 0;
    }

    .auto-repeat-input {
        width: 20px;
        height: 40px;
        /* position: relative;
        top: -2.5px;
        left: -5px; */
        cursor: text;
        /* vertical-align: middle; */
        /* background-color: #fff; */
        /* padding-right: 20px; */
        padding: 0;
    }
</style>